﻿/************************************************************************
 * SMLib - State Model Library
 * Copyright (C) 2012-2013 Ali Khalili (khalili_DOT_ir_@SIGN_gmail_DOT_com)
 * **********************************************************************
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License (LGPL) published 
 * by the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version. This program is distributed without any
 * warranty. See the GNU Lesser General Public License for more details. 
 * ***********************************************************************
 * File         :     SMLib\Interoperability\GML\GmlHelper.cs
 * Description  :     GML (Graph modeling language) helper
 * Change log   :     -1 Sep 2013:  Initial Version
 * To Do        :     It is not supporting many features of GML
 ************************************************************************/
using System;
using System.Collections.Generic;
using SMLib.Base;
using System.IO;
using System.Text;

namespace SMLib.Interoperability.GML
{
    /// <summary>
    /// Interface for GML helper
    /// </summary>
    /// <typeparam name="STATETYPE">type of states</typeparam>
    /// <typeparam name="TRANSITIONTYPE">type of transitions</typeparam>
    public interface IGmlHelper<STATETYPE, TRANSITIONTYPE>
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        Dictionary<string, string> PropertiesOf(STATETYPE state);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        Dictionary<string, string> PropertiesOf(TRANSITIONTYPE state);


        TRANSITIONTYPE TransitionOf(Dictionary<string, string> trProp);


        STATETYPE StateOf(Dictionary<string, string> stProp);
    }

    /// <summary>
    /// Helper for GML: Graph Modeling Language which is an XML based format to represent graphs
    /// <see cref="http://en.wikipedia.org/wiki/Graph_Modelling_Language"/>
    /// </summary>
    public class GmlHelper<StateType,TransitionType>
    {
        /// <summary>
        /// Write to GML file
        /// </summary>
        /// <param name="ss"></param>
        /// <returns></returns>
        public string WriteToGML(IDiGraph<StateType,TransitionType> ss)
        {
            StringBuilder GMLString = new StringBuilder();
            int i = 0;
            GMLString.AppendLine("<graphml>");
            GMLString.AppendLine("\t<graph>");
            foreach (StateType st in ss.GetStates())
            {
                i++;
                GMLString.AppendLine("\t\t<node id=\"" + VertexToVertexID(st) + "\"/>");
                foreach (TransitionType tr in ss.TransitionsOf(st))
                {
                    GMLString.AppendLine("\t\t\t<edge id=\"" + EdgeToEdgeID(tr) + "\" source=\"" + VertexToVertexID(st) + "\" destination=\"" +
                	                     VertexToVertexID(ss.DestinationOf(tr)) + "\"/>");
                }
            }
            GMLString.AppendLine("\t</graph>");
            GMLString.AppendLine("\t</graphml>");
            return GMLString.ToString();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="path"></param>
        /// <param name="ss"></param>
        public void WriteToGML(string path, IDiGraph<StateType,TransitionType> ss)
        {
            File.WriteAllText(path, WriteToGML(ss));
        }

        public TransitionType ReadFromGml(string path)
        {
        	throw new NotImplementedException();
        }

        #region -=[ To Be Overrided ]=-

        /// <summary>
        /// Convert a vertex to string (for export porpuse)
        /// </summary>
        /// <param name="state">the state</param>
        /// <returns>the string</returns>
        protected virtual string VertexToVertexID(StateType state)
        {
            return state.ToString();
        }

        /// <summary>
        /// Converting an edge to string (for export porpuse)
        /// </summary>
        /// <param name="tr">the transition</param>
        /// <returns>the equivalent string</returns>
        protected virtual string EdgeToEdgeID(TransitionType tr)
        {
            return tr.ToString();
        }

        /// <summary>
        /// Convert a string into the proper transition (for import porpose)
        /// </summary>
        /// <param name="tr">the string</param>
        /// <returns>the equivalent transition</returns>
        protected virtual TransitionType EdgeIdToEge(string tr)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Convert a string into a state (for import porpose)
        /// </summary>
        /// <param name="st">the string</param>
        /// <returns>the equivalent state</returns>
        protected virtual IStateContainer VertexIdToVertex(string st)
        {
            throw new NotImplementedException();
        }
        #endregion


    }
}
